package string;

/**
 * String常量池
 * java推荐我们使用字面量形式创建字符串，并且会缓存字面量创建的字符串对象
 * 使用相同字面量创建的字符串会重用对象
 */
public class StringDemo {
    public static void main(String[] args) {
        String s1 = "123abc";
        String s2 = "123abc";//相同字面量重用对象
        System.out.println("s1==s2:"+(s1==s2));//true
        String s3 = "123abc";//一样重用对象
        System.out.println("s1==s3:"+(s1==s3));
        /*
            new是比较强制的操作，一定会创建新对象
            java不推荐我们这样创建字符串，因为new的对象都不会放到常量池中重用对象
         */
        String s4 = new String("123abc");
        System.out.println("s4:"+s4);
        System.out.println("s1==s4:"+(s1==s4));//地址不同
        //String是不变对象，即:对象创建后内容不可改变，若改变一定会创建新对象
        System.out.println("s1:"+s1);//123abc
        s1 = s1 + "!";//s1:123abc!  "123abc!"是一个新对象，将地址赋值给s1
        System.out.println("s1:"+s1);//123abc!
        System.out.println("s2:"+s2);//123abc  s2还指向原常量池中的对象
        System.out.println("s1==s2"+(s1==s2));//false
        /*
            编译器的预编译特性:
            编译器在编译源代码时如果发现一个计算表达式计算符两侧都是字面量时，会直接进行
            计算，并将结果替换改表达式，避免JVM每次执行时再进行计算了。
            为什么要这样做:
            int t = 1000*60*60*24;  该计算表达式更好说明了值的意思
            但实际上并不会影响性能，因为编译器会直接计算结果
            int t = 86400000;
         */
        String s5 = "123"+"abc";
        System.out.println("s2==s5:"+(s2==s5));//true  s5指向常量池中重用的对象


        String s = "123";
        String s6 = s + "abc";
        System.out.println("s2==s6:"+(s2==s6));


    }
}



